package org.tinygroup.earthworm3;

public class EarthWorm3 {
	private static final String ROOT_SPAN_ID = "1";
	private static final String MAL_ROOT_SPAN_ID = "1";
	private static LogService3 logService = LogService3.getInstance();

	public static void startTrace(String traceId, String traceName) {
		startTrace(traceId, (String) null, traceName);
	}

	public static void startTrace(String traceId, String spanId, String traceName) {
		if (traceName != null) {
			traceId = EarthWormHelper3.trim(traceId);
			if (!EarthWormHelper3.validTraceId(traceId)) {
				traceId = EarthWormHelper3.generate();
				spanId = ROOT_SPAN_ID;
			} else if (!EarthWormHelper3.validSpanId(spanId)) {
				spanId = ROOT_SPAN_ID;
			}
			RpcContext3 ctx = RpcContext3.get();
			if (ctx != null && ctx.traceId != null) {
				if (ctx.traceId.equals(traceId) && traceName.equals(ctx.traceName)) {
					return;
				}
				endTrace();
			}
			try {
				RpcContext3 ctx2 = new RpcContext3(traceId, spanId);
				RpcContext3.set(ctx2);
				ctx2.startTrace(traceName);
			} catch (Throwable var5) {
			}
			logService.logStage("starttrace");
		}
	}

	public static void endTrace() {
		logService.logStage("endtrace");
		try {
			RpcContext3 re = RpcContext3.get();
			if (null == re) {
				return;
			}

			while (null != re.parent) {
				re = re.parent;
			}
			re.endTrace();
		} finally {
			clearRpcContext();
		}

	}

	public static void startLocal(String serviceName, String methodName) {
		startLocal("", serviceName, methodName);
	}

	public static void startLocal(String traceName, String serviceName, String methodName) {
		RpcContext3 re = RpcContext3.get();
		re.startLocal(serviceName, methodName, traceName);
		logService.logStage("startlocal");
	}

	public static void endLocal() {
		
		RpcContext3 re = RpcContext3.get();
		if (null == re) {
			return;
		}
		re.endLocal();
		logService.logStage("endlocal");
	}

	public static void startRpc(String serviceName, String methodName) {

		RpcContext3 re = RpcContext3.get();
		if (null == re) {
			re = new RpcContext3(EarthWormHelper3.generate(), ROOT_SPAN_ID);
		}
		RpcContext3.set(re);
		re.startRpc(serviceName, methodName);
		logService.logStage("startrpc");
	}

	public static void rpcClientSend() {
		RpcContext3 re = RpcContext3.get();
		if (null == re) {
			logService.logStage("rpcClientSend");
			return;
		}
		re.rpcClientSend();
		logService.logStage("rpcClientSend");
	}


	public static void rpcClientRecv() {
		logService.logStage("rpcClientRecv");
		RpcContext3 re = RpcContext3.get();
		if (null == re) {
			return;
		}
		re.endRpc();

	}

	public static void rpcServerRecv(String service, String method) {
		try {
			createContextIfNotExists(true).rpcServerRecv(service, method);
		} catch (Throwable var3) {
		}
		logService.logStage("rpcServerRecv");
	}


	public static void rpcServerSend() {
		try {
			RpcContext3 re = RpcContext3.get();
			if (re != null) {
				re.rpcServerSend();

			}
			logService.logStage("rpcServerSend");
		} finally {
			clearRpcContext();
		}

	}

	public static String getTraceId() {
		RpcContext3 ctx = RpcContext3.get();
		return null == ctx ? null : ctx.traceId;
	}

	public static String getSpanId() {
		RpcContext3 ctx = RpcContext3.get();
		return null == ctx ? null : ctx.spanId;
	}

	public static RpcContext3 getRpcContext() {
		return RpcContext3.get();
	}

	public static RpcContext3 createRootRpcContext(String traceId, String rpcId) {
		if (traceId == null) {
			traceId = EarthWormHelper3.generate();
		}

		if (rpcId == null) {
			rpcId = MAL_ROOT_SPAN_ID;
		}

		return new RpcContext3(traceId, rpcId);
	}

	static final RpcContext3 createContextIfNotExists(boolean setToThreadLocal) {
		RpcContext3 ctx = RpcContext3.get();
		if (null == ctx) {
			RpcContext3 newCtx = new RpcContext3(EarthWormHelper3.generate(), MAL_ROOT_SPAN_ID);
			if (setToThreadLocal) {
				RpcContext3.set(newCtx);
			}
			return newCtx;
		} else {
			return ctx;
		}
	}

	public static void setRpcContext(RpcContext3 context) {
		RpcContext3.set(context);
	}

	public static void clearRpcContext() {
		RpcContext3.set(null);
		logService.clear();
	}

}
